// Find global reference - uses 'this' by default when available,
// falls back to 'window' otherwise (for bundlers like Webpack)
var globalRef = typeof this !== 'undefined' ? this : window

// The main wrapping element
var SVG = (globalRef.SVG = function (element) {
    if (SVG.supported) {
        element = new SVG.Doc(element)

        if (!SVG.parser.draw) SVG.prepare()

        return element
    }
})

// Default namespaces
SVG.ns = 'http://www.w3.org/2000/svg'
SVG.xmlns = 'http://www.w3.org/2000/xmlns/'
SVG.xlink = 'http://www.w3.org/1999/xlink'
SVG.svgjs = 'http://website/svgjs'

// Svg support test
SVG.supported = (function () {
    return (
        !!document.createElementNS &&
        !!document.createElementNS(SVG.ns, 'svg').createSVGRect
    )
})()

// Don't bother to continue if SVG is not supported
if (!SVG.supported) return false

// Element id sequence
SVG.did = 1000

// Get next named element id
SVG.eid = function (name) {
    return 'Svgjs' + capitalize(name) + SVG.did++
}

// Method for element creation
SVG.create = function (name) {
    // create element
    var element = document.createElementNS(this.ns, name)

    // apply unique id
    element.setAttribute('id', this.eid(name))

    return element
}

// Method for extending objects
SVG.extend = function () {
    var modules, methods, key, i

    // Get list of modules
    modules = [].slice.call(arguments)

    // Get object with extensions
    methods = modules.pop()

    for (i = modules.length - 1; i >= 0; i--)
        if (modules[i])
            for (key in methods) modules[i].prototype[key] = methods[key]

    // Make sure SVG.Set inherits any newly added methods
    if (SVG.Set && SVG.Set.inherit) SVG.Set.inherit()
}

// Invent new element
SVG.invent = function (config) {
    // Create element initializer
    var initializer =
        typeof config.create == 'function'
            ? config.create
            : function () {
                  this.constructor.call(this, SVG.create(config.create))
              }

    // Inherit prototype
    if (config.inherit) initializer.prototype = new config.inherit()

    // Extend with methods
    if (config.extend) SVG.extend(initializer, config.extend)

    // Attach construct method to parent
    if (config.construct)
        SVG.extend(config.parent || SVG.Container, config.construct)

    return initializer
}

// Adopt existing svg elements
SVG.adopt = function (node) {
    // check for presence of node
    if (!node) return null

    // make sure a node isn't already adopted
    if (node.instance) return node.instance

    // initialize variables
    var element

    // adopt with element-specific settings
    if (node.nodeName == 'svg')
        element =
            node.parentNode instanceof window.SVGElement
                ? new SVG.Nested()
                : new SVG.Doc()
    else if (node.nodeName == 'linearGradient')
        element = new SVG.Gradient('linear')
    else if (node.nodeName == 'radialGradient')
        element = new SVG.Gradient('radial')
    else if (SVG[capitalize(node.nodeName)])
        element = new SVG[capitalize(node.nodeName)]()
    else element = new SVG.Element(node)

    // ensure references
    element.type = node.nodeName
    element.node = node
    node.instance = element

    // SVG.Class specific preparations
    if (element instanceof SVG.Doc) element.namespace().defs()

    // pull svgjs data from the dom (getAttributeNS doesn't work in html5)
    element.setData(JSON.parse(node.getAttribute('svgjs:data')) || {})

    return element
}

// Initialize parsing element
SVG.prepare = function () {
    // Select document body and create invisible svg element
    var body = document.getElementsByTagName('body')[0],
        draw = (
            body
                ? new SVG.Doc(body)
                : SVG.adopt(document.documentElement).nested()
        ).size(2, 0)

    // Create parser object
    SVG.parser = {
        body: body || document.documentElement,
        draw: draw
            .style(
                'opacity:0;position:absolute;left:-100%;top:-100%;overflow:hidden'
            )
            .attr('focusable', 'false').node,
        poly: draw.polyline().node,
        path: draw.path().node,
        native: SVG.create('svg'),
    }
}

SVG.parser = {
    native: SVG.create('svg'),
}

document.addEventListener(
    'DOMContentLoaded',
    function () {
        if (!SVG.parser.draw) SVG.prepare()
    },
    false
)
